package com.qd.hik.token;

import com.cdqidi.util.AnnotationUtil;
import com.qd.hik.dto.token.HkTokenResp;
import com.qd.hik.service.HkTokenService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * @author sjk
 */
@Aspect
@Component
@AutoConfiguration
@Slf4j
public class HkAccessTokenAspect {
    private final HkTokenService hkTokenService;


    public HkAccessTokenAspect(HkTokenService hkTokenService) {
        this.hkTokenService = hkTokenService;
        log.info("HkAccessTokenAspect init");
    }

    /**
     * 横切点
     */
    @Pointcut("@annotation(com.qd.hik.token.HkAccessToken)")
    public void accessTokenPointCut() {
    }

    /**
     * 表示拦截类和方法
     *
     * @param joinPoint 截面
     */
    @Before(value = "@within(com.qd.hik.token.HkAccessToken) || accessTokenPointCut()")
    @SneakyThrows
    public void doBefore(JoinPoint joinPoint) {
        HkAccessToken accessToken = Optional.ofNullable(AnnotationUtil.getClassAnnotation(joinPoint, HkAccessToken.class))
                .orElse(AnnotationUtil.getMethodAnnotation(joinPoint, HkAccessToken.class));
        if (log.isDebugEnabled()) {
            log.debug("accessToken isExists: {}", null != accessToken);
        }
        if (null == accessToken) {
            return;
        }
        HkTokenResp hkTokenResp = HkAccessTokenManager.getToken();
        if (null == hkTokenResp) {
            hkTokenResp = hkTokenService.getTokenSync();
            HkAccessTokenManager.setToken(hkTokenResp);
        }
        if (log.isDebugEnabled()) {
            log.debug("accessToken: {}", hkTokenResp.getAccessToken());
        }
    }

    @After(value = "@within(com.qd.hik.token.HkAccessToken) || accessTokenPointCut()")
    public void after() {
        if (log.isDebugEnabled()) {
            log.debug("after,accessToken clear");
        }
        HkAccessTokenManager.clear();
    }
}